
#include "Record.h" 

class IndexRecord : public Record {

public:

	int Compare (IndexRecord &withMe, Type myType);
	int Compare (char *keyVal, Type mytype);

	// this takes and copies the key, pointer pair into the record.  
	// keyLen is the number of bytes in the key.
	void Load (char *key, int keyLen, int pointer);

	// this gets the pointer value associated with the record
	int GetPointer ();

	char *GetKey ();

	// contsructor
	IndexRecord ();
}; 

class BPlusTree {
	
	// this is the File object that actually stores the B+-Tree
	File whereILive;

	// this is the name of the file that actually stores the B+-Tree
	char *fileName;

	// this is the type of the key value that is stored in the tree
	Type keyType;

	// this is the number of pages in the tree
	int numPages;

	// this is the height of the tree
	int height;

	// this is the ID of the page that contains the root of the tree
	int rootLocation;

	// private functions
	int Insert (char *keyVal, int pageID, Page &curPage, int pageAddress, int heightToGo, char *&splitKey);
	int Split (Page &curPage, int pageAddress, IndexRecord &foo, char *&splitKey);
	IndexRecord *GetPage (Page &curPage, int height2Go, char *keyVal, int &numReturned);
	IndexRecord *GetNext (Page &curPage, int height2Go, int &numReturned);
	char *GetMax ();
	void Load (IndexRecord &foo, char *keyVal, int pageID);

	// used for GetNext
	int *stack;

public:

	// this inserts a new (key, pointer) pair into the tree
	void Insert (char *keyVal, int pageID);

	// this returns a pointer to all of the index records on the first page in the tree
	// that contains the key value keyVal.  Note that it is assumed that the CALLER will
	// deallocate the memory returned by this function
	IndexRecord *GetPage (char *keyVal, int &numReturned);

	// this returns a pointer to all of the index records on the next page of the tree,
	// where "next" is defined as the page that comes after the last one that was obtained
	// by GetPage or GetNext.  The return value is 0 if there are no more pages.
	// So to implement a range query from low to high, you would first call GetPage using
	// low, and then keep on calling GetNext until you finally get a record whose key
	// value exceeds high
	IndexRecord *GetNext (int &numReturned);

	// this closes the B+-Tree; this must be called for the tree to be "re-openable"
	void Close ();

	// this opens up an already existing tree; the actual binary file that
	// stores the tree is located in the file named as the input parameter.
	// Also, it is assumed that there is a text file of the same name, 
	// except that it has the extension ".info" that contains all of the
	// important information that the tree needs to open up an
	// already-existing tree file.  The format is:
	//
	// keyType: Int
	// numPages: 27
	// height: 3
	// rootLocation: 13
	//
	// For example, say that fName = "myTree".  Then the file "myTree" 
	// would hold a binary database file that stores the tree, and the file
	// "myTree.info" would have a text file, four lines long, that gives 
	// the key type for the tree, the number of pages in the tree, the
	// height of the tree, and the page number for the root.
	// 
	// The return value is a 1 on success, and a 0 on failure.
	int Open (char *fName);

	// this creates a brand new B+-Tree.  It will be stored at the location
	// indicated by the parameter, and it will store (key, ptr) pairs where
	// the key is of the type indicated.
	int Create (char *fName, Type keyType);

	// this is the destructor.  The destructor should close whereILive,
	// and then write out the correpsonding ".info" file so that the tree
	// can be opened up once again at some future time.
	~BPlusTree ();

	// this is the constructor.
	BPlusTree ();
};

